#include <iostream>

/*
 * Target
 * defines specific interface that client uses
*/
class Target
{
public:
    virtual ~Target() {}
    virtual void request() = 0;
};

/*
 * Adaptee
 * all requests get delegated to the Adaptee which defines
 * an existing interface that needs adapting
*/
class Adaptee
{
public:
    ~Adaptee() {}

    void specificRequest()
    {
        std::cout << "specific request" << std::endl;
    }
};

/*
 * Adapter
 * implements the Target interface and lets the Adaptee respond
 * to request on a Target by extending both classes
 * ie adapts the interface of Adaptee to the Target interface
 */
class AdapterClass : public Target, private Adaptee
{
public:
    virtual void request()
    {
        specificRequest();
    }
};

class AdapterObject : public Target
{
public:
    AdapterObject() : adaptee() {}

    ~AdapterObject()
    {
        delete adaptee;
    }

    virtual void request()
    {
        adaptee->specificRequest();
    }

private:
    Adaptee *adaptee;
};

int main()
{
    Target *t = nullptr;

    t = new AdapterClass();
    t->request();

    delete t;

    t = new AdapterObject();
    t->request();

    delete t;

    return 0;
}